<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="UTF-8">
		<title></title>
	</head>
	<body>
		<script type="text/javascript">
			// https://blog.csdn.net/qq_49900295/article/details/128077147
			// js 中的类型分为 值类型和引用类型，值类型 保存在 内存栈 中，引用类型 保存在 内存堆 中。
			// 所以说js中函数的参数都是按值传递的
			/*
			JS的函数参数传递是按值传递, 只不过这里的值是指栈区的值。
			无论形参是值类型还是引用类型的值，在函数里都会复制出一份新的栈区值指向它们，
			如果形参是值类型的，新复制出来的栈区值是自己本身的值，此时无论如何修改形参的值都不会影响到实参。
			如果形参是引用类型，新复制出来的栈区值是指向堆中具体的某一个对象，
			　1、当传入形参的对象是原先就有的，那么形参与实参都共同指向该对象，此时修改形参的值就会影响到原先对象的值。
			　2、当传入形参的对象是新的对象，那么形参指向该新对象，此时无论如何修改形参的值都不会影响到实参。
			我们解析函数的形参是对象时，最好使用const加解构的方式去解析或者使用JSON重新创建出一个新对象，从而避免莫名奇妙修改了值。
			*/
		 
		 {
		 	var a = {
		 		name: '大雄'
		 	};
		 	var b = a;
		 	b.name = '小熊';
		 	console.log(a.name);
		 }
		 
		 {
		 	var a = [1, 2, 3]
		 	function fn(b) {
		 		b = [4, 5, 6];
		 	};
		 	fn(a)
		 	console.log(a);
		 }

			{
				var value = 1;
				function foo(v) {
					v = 2;
				}
				console.log(value); // 1
				foo(value);
				console.log(value) // 1
			}
			
			{
				var v = 1;
				function vfn() {
					v = 2;
				}
				console.log(v, 'v1'); // 1
				vfn(v);
				console.log(v, 'v2') // 1
			}

			{
				var obj = {
					value: 1
				};
				function foo(o) {
					o.value = 2;
					console.log(o.value); // 2
				}
				foo(obj);
				console.log(obj.value) // 2
			}

			{
				var testA = 1;
				var testB = {};
				function testNumber(example) {
					example = 2;
				}
				function testObj(example) {
					example.test = 1;
				}
				testNumber(testA);
				testObj(testB);
				console.log(testA); // 输出1
				console.log(testB); // 输出{ test: 1 }
			}

			{
				var testC = {};
				function testObject(example) {
					example = {
						b: 1
					};
				}
				testObject(testC)
				console.log(testC); // 输出{}，实参并没有改变
			}

			{
				function demo(obj) {
					const {
						a,
						b,
						...datas
					} = obj || {}
				}
				function demo(obj) {
					const copy = JSON.parse(JSON.stringify(obj))
				}
			}
		</script>
	</body>
</html>